#ifndef fuzzy_pid_h
#define fuzzy_pid_h

/*论域的取值   ！！！非常重要
我们把  E的论域定为[-3,3] , EC的论域为[-3,3]
*/

//论域相关参数
typedef struct{
	
	  //论域统一
		int Fuzzy_Pid_D_T;     //论域最大值
		int Fuzzy_Pid_D_B;     //论域最低值
	
		float Gather_T;        //采集最大值     采集的区间[Gather_B,Gather_T]
		float Gather_B;        //采集最小值
	
		float E;               //当前误差
		float EC;              //与上次误差的误差变化率
		float LastError;       //上一次的误差 Error[-1]
		float PrevError;       //上上次的误差 Error[-2]
	
		float E_K;            //采集到的值与E的论域的系数比例,实际测得,量化因子
		float EC_K;           //采集到的值与EC的论域的系数比例,实际测得,量化因子
	
		float E_D_P;          //E在论域中的位置
		float EC_D_P;         //EC在论域中的位置
		
		//E的采集值到论域的转化，看.h
	
		float KP;
		float KI;
	  float KD;
		
		float KP_K;           //量化因子 deltkp=KP_K*U值
		float KI_K;           //量化因子 deltki=KI_K*U值
		float KD_K;           //量化因子 deltkd=KD_K*U值
		
		float K1;             // 增量式系数   K1=KP+KI+KD  K2=-(KP+2*KD)  K3=KD
	  float K2;
		float K3;
		
		//进行限幅
		float Pwm_Out_Max;    //pwm输出最大值
		float Pwm_Out_Min;    //pwm输出最小值
		float PWM_out;        //pwm的实际输出值
		float det_PWM;        //pwm输出的增量值
		float PWM_ZERO;       //零位
		
		int   Type;           //标志这是电流还是位置
		
		int   Init_Flag;      //初始化标志，0：未初始化  1：初始化      

}Fuzzy_PID_S;



typedef struct{
     int Input_val_max;    //输入信号的最大值，外部输入的话1V对应1000，上位机多少就是多少
	   int Input_val_min;    //输入信号的最小值，外部输入的话1V对应1000，上位机多少就是多少
	   
	   float E_S;            //E误差对于全量程的缩放，0.1就是缩放成全量程的1/10，例如测量的全程为1000，E_S为0.1时，100对应论域的3，-100对应论域的-3
	   float EC_S;           //EC误差对于全量程的缩放，意义类似
	
		 float KP_DYMIC;       //KP每次变动的范围[-KP_DYMIC,+KP_DYMIC]
		 float KI_DYMIC;       //KI每次变动的范围[-KI_DYMIC,+KI_DYMIC]
		 float KD_DYMIC;       //KD每次变动的范围[-KD_DYMIC,+KD_DYMIC]
	
	
		 float KP_Max;         //设置在模糊PID中的最大值，KP_Max要>=0
	   float KI_Max;         //设置在模糊PID中的最大值，KI_Max要>=0
		 float KD_Max;         //设置在模糊PID中的最大值，KI_Max要>=0
	
	   float Num_Index;      //模糊子集的大小，越小计算越省，但是精度越差，反之越高计算压力越大，但是精度越高，0<Num_Index<=N(论域点的个数)
	   
		 int Switch_on;      	 //模糊PID开关 
	   
	   int  Type;            //标志这是电流还是位置
}Fuzzy_PID_Control_S;


void  Fuzzy_PID_init(Fuzzy_PID_S* Fuzzy_pid,Fuzzy_PID_Control_S* Fuzzy_pid_control,int Type);  		//模糊PID初始化, Fuzzy_pid:模糊PID ,Fuzzy_pid_control:模糊PID控制参数 Type：控制电流还是位移
float FTri(float x,float a,float b,float c);		//FuzzyTriangle,三角隶属度函数
float FTraL(float x,float a,float b);           //FuzzyTrapezoidLeft,梯形左求隶属度
float FTraR(float x,float a,float b);           //FuzzyTrapezoidRight,梯形右求隶属度
void Fuzzy_PID_Realize(Fuzzy_PID_S *Fuzzy_pid,Fuzzy_PID_Control_S* Fuzzy_pid_control,float Target,float Feedback); //模糊PID实现

void  Fuzzy_PID(void);    //模糊PID
void  Fuzzy_PID_Control(Fuzzy_PID_S *Fuzzy_pid,Fuzzy_PID_Control_S* Fuzzy_pid_control,int Type);     //模糊PID参数的控制
#endif